package com.itheima.sh.user.service.impl;

import com.itheima.sh.pojo.Order;
import com.itheima.sh.pojo.User;
import com.itheima.sh.request.dtos.UserQueryDTO;
import com.itheima.sh.response.vos.OrderVO;
import com.itheima.sh.response.vos.UserOrdersVO;
import com.itheima.sh.user.feign.OrderApi;
import com.itheima.sh.user.mapper.UserMapper;
import com.itheima.sh.user.service.UserService;
import org.dozer.Mapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @Description:
 * @Version: V1.0
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return
     */
    @Override
    public User findUserById(String username) {
        return userMapper.selectByPrimaryKey(username);
    }


    @Autowired
    OrderApi orderApi;

    @Autowired
    Mapper mapper;

    /**
     * 根据用户登录名查询订单列表
     *
     * @param username DTO：
     *                 VO：
     *                 POJO：
     */
    @Override
    public UserOrdersVO findOrderByUserId(String username) {
        // 参数校验 username
        if (StringUtils.isEmpty(username)) {
            throw new RuntimeException("参数非法");
        }

        // 根据用户名查询用户信息  --- 本地调用
        User user = this.findUserById(username);
        // JDK 对对象非空判断做的规范
        Optional<User> optional = Optional.ofNullable(user);
        if (!optional.isPresent()) {
            throw new RuntimeException("查无此人");
        }

        // 根据用户名查询订单列表  --- feign 远程调用
        List<Order> orderList = orderApi.findOrderByUserId(username);

        UserOrdersVO userOrdersVO = new UserOrdersVO();
        // userOrdersVO.setUsername(user.getUsername());  不推荐
        // 原对象中属性名称和目标对象的属性名称保存一致才可以封装
//        BeanUtils.copyProperties(optional.get(), userOrdersVO);
        mapper.map(optional.get(), userOrdersVO);

        List<OrderVO> orders = new ArrayList<>();
        // 遍历List集合
        for (Order order : orderList) {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(order, orderVO);

            orders.add(orderVO);
        }
        userOrdersVO.setOrders(orders);
        // 各种O装换的框架： MapStruct  Dozer  BeanUtils（Spring）


        // 封装查询结果并返回
//        Map<String, Object> map = new HashMap<>();
//        map.put("user", optional.get());
//        map.put("orderList", orderList);

        /**
         * 封装的返回结果存在扫描问题？
         * 1、返回值可读性不强
         * 2、存在接口信息暴露问题
         * 3、无用字段增多，增加了网络传输带宽
         *
         * 各种O解决：
         * DTO： 前端 --> 后端发送请求的时候传递到 业务层的 对象
         * VO：  后端 --> 响应给前端的对象
         *
         *
         * POJO：简单实体类，和数据库建立关系
         */

        return userOrdersVO;
    }


    /**
     * 根据条件查询用户所属订单列表
     *
     * @param userQueryDTO
     * @return
     */
    @Override
    public UserOrdersVO findOrders(UserQueryDTO userQueryDTO) {


        // 参数校验 username
        if (StringUtils.isEmpty(userQueryDTO)) {
            throw new RuntimeException("参数非法");
        }

        // 根据用户名查询用户信息  --- 本地调用
        User user = this.findUserById(userQueryDTO.getUsername());
        // JDK 对对象非空判断做的规范
        Optional<User> optional = Optional.ofNullable(user);
        if (!optional.isPresent()) {
            throw new RuntimeException("查无此人");
        }

        // 根据用户名查询订单列表  --- feign 远程调用
        List<Order> orderList = orderApi.findOrderByUserId(user.getUsername());

        UserOrdersVO userOrdersVO = new UserOrdersVO();
        // userOrdersVO.setUsername(user.getUsername());  不推荐
        // 原对象中属性名称和目标对象的属性名称保存一致才可以封装
//        BeanUtils.copyProperties(optional.get(), userOrdersVO);
        mapper.map(optional.get(), userOrdersVO);

        List<OrderVO> orders = new ArrayList<>();
        // 遍历List集合
        for (Order order : orderList) {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(order, orderVO);

            orders.add(orderVO);
        }
        userOrdersVO.setOrders(orders);



        return userOrdersVO;
    }
}
